package org.jeecg.modules.common.baseservice;

import com.alibaba.fastjson.JSONObject;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.common.api.IRow2ColTransfer;
import org.jeecg.modules.common.baseentity.Row2ColModel;
import org.jeecg.modules.common.utils.BeanObjUtil;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Service
public class Row2ColTransfer implements IRow2ColTransfer {
    /**
     * 行转列方法，返回List<JSONObject>
     * @param dataList
     * @return List<JSONObject>
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    @Override
    public List<JSONObject> Row2ColToListJson(List dataList, Row2ColModel row2ColModel) throws NoSuchFieldException, IllegalAccessException {
        if(oConvertUtils.listIsEmpty(dataList) || oConvertUtils.isEmpty(row2ColModel) || oConvertUtils.isEmpty(row2ColModel.getGroupFields() )){
            return null;
        }

        List<JSONObject> resultJSONList = new ArrayList<JSONObject>();
        int rowCount = 0;  //行数
        int colCount = 0;  //列数
        List<Object> newColNamesList = new ArrayList<Object>();

        //第一遍循环，取固定分组列
        for(Object rowdata : dataList) {
            int rowdataColCount = 0;
            JSONObject rowJSON = new JSONObject();
            boolean insetflag = false;
            for ( int i=0;i< row2ColModel.getGroupFields().length;i++ ) {
                int list_i = oConvertUtils.isNotEmpty(row2ColModel.getGroupFieldsAsName()) ? BeanObjUtil.getObjFromListIndex(rowdata,row2ColModel.getGroupFields(),resultJSONList,row2ColModel.getGroupFieldsAsName())
                        : BeanObjUtil.getObjFromListIndex(rowdata,row2ColModel.getGroupFields(),resultJSONList,row2ColModel.getGroupFields());
                //如果属性存在 且未处理过(不存在）
                if(BeanObjUtil.isExistField(row2ColModel.getGroupFields()[i],rowdata) && list_i==-1 ){
                    //获取属性值
                    Object rowdataObjFieldValue = BeanObjUtil.getFieldValueByName(rowdata,row2ColModel.getGroupFields()[i]);
                    String objfieldValue = oConvertUtils.isEmpty(rowdataObjFieldValue) ? "空null" : rowdataObjFieldValue.toString();// colnamefield.get(rowdata).toString();

                    if(oConvertUtils.isNotEmpty(row2ColModel.getGroupFieldsAsName()[i])){
                        rowJSON.put((String) row2ColModel.getGroupFieldsAsName()[i],objfieldValue );
                        rowdataColCount++; //列数累加
                        if (!newColNamesList.contains(row2ColModel.getGroupFieldsAsName()[i])) { // 如果新集合中不存在则插入
                            newColNamesList.add(row2ColModel.getGroupFieldsAsName()[i]);
                        }
                    }
                    else{
                        rowJSON.put(row2ColModel.getGroupFields()[i],objfieldValue);
                        rowdataColCount++; //列数累加
                        if (!newColNamesList.contains(row2ColModel.getGroupFields()[i])) { // 如果新集合中不存在则插入
                            newColNamesList.add(row2ColModel.getGroupFields()[i]);
                        }
                    }
                    insetflag = true;
                }
                //计算最大列数
                colCount = colCount>rowdataColCount ? colCount : rowdataColCount;
            }
            //不重复的，应该记录数据
            if (insetflag){
                resultJSONList.add(rowJSON);
                rowCount++;
            }
        }
        row2ColModel.setRowCount(rowCount); //设置行数
//        colCount = colCount; 列数
        //第2遍循环，取动态列，按列增加到JSONObject后面
        int newColCount = 0;
        for(Object rowdata : dataList) {
            if(oConvertUtils.isEmpty(row2ColModel.getRow2colsKeyFields())){
                break;
            }
            //行转列关键字段：如 科目subjectId，其值会直接作为列名返回
            for(int i=0;i<row2ColModel.getRow2colsKeyFields().length;i++){
                int list_i = oConvertUtils.isNotEmpty(row2ColModel.getGroupFieldsAsName()) ?
                        BeanObjUtil.getObjFromListIndex(rowdata,row2ColModel.getGroupFields(),resultJSONList,row2ColModel.getGroupFieldsAsName())
                        : BeanObjUtil.getObjFromListIndex(rowdata,row2ColModel.getGroupFields(),resultJSONList,row2ColModel.getGroupFields());

                //如果属性存在，且在记录中，则添加字段
                if(BeanObjUtil.isExistField(row2ColModel.getRow2colsKeyFields()[i],rowdata) && list_i>=0 ){
                    JSONObject rowJSON = resultJSONList.get(list_i);



                    //获取属性值
                    Object rowdataObjFieldValue = BeanObjUtil.getFieldValueByName(rowdata,row2ColModel.getRow2colsKeyFields()[i]);
                    String colname = oConvertUtils.isEmpty(rowdataObjFieldValue) ? "空null" : rowdataObjFieldValue.toString();// colnamefield.get(rowdata).toString();

                    //权重系数:每一列对应的权重系数，用于计算汇总形成汇总新列，如sum count 等
                    //key=列名，例如：语文WeightCoefficient 英语WeightCoefficient
                    //value=数值，例如：0.5 0.2
                    if(oConvertUtils.isEmpty(colname) ){
                        continue;
                    }
                    if( oConvertUtils.isNotEmpty(row2ColModel.getNewValueWeightCoefficientFieldes()) && oConvertUtils.isNotEmpty(row2ColModel.getNewWeightCoefficientAsColName()) ){
                        //获取属性值
                        rowdataObjFieldValue = BeanObjUtil.getFieldValueByName(rowdata,row2ColModel.getNewValueWeightCoefficientFieldes());
                        String sumWeightCoefficientValue = oConvertUtils.isEmpty(rowdataObjFieldValue) ? null : rowdataObjFieldValue.toString();
                        //权重所在的列名：例如：语文权=0.1 数学权=0.1 优权=1 良权=1等
                        String newColName ;

                        //是否有转义字典码
                        if(oConvertUtils.isEmpty(row2ColModel.getRow2colsKeyFieldsDict()) || oConvertUtils.isEmpty(row2ColModel.getRow2colsKeyFieldsDict()[i].get(colname)) ){
                            //没有转义字典码
                            newColName = (String) colname + row2ColModel.getNewWeightCoefficientAsColName();
                        }else{
                            //有转义字典码
                            newColName = row2ColModel.getRow2colsKeyFieldsDict()[i].get(colname) + row2ColModel.getNewWeightCoefficientAsColName();
                        }


                        rowJSON.put(newColName, sumWeightCoefficientValue);

                        if (!newColNamesList.contains(newColName)) { // 如果新集合中不存在则插入
                            newColNamesList.add(newColName);
                            newColCount++;//新增列数加1
                        }
                    }
                    //获取属性值：单元格数值
                    JSONObject cellValue = new JSONObject();
                    for(int k=0;k<row2ColModel.getNewColsValueByFields().length ;k++) {
                        rowdataObjFieldValue = BeanObjUtil.getFieldValueByName(rowdata, row2ColModel.getNewColsValueByFields()[k]);
//                        String colvalue;
//                        if(row2ColModel.getNewColsValueByFields().length==1){}
//                        else if(row2ColModel.getNewColsValueByFields().length>1){}


                        String colvalue = oConvertUtils.isEmpty(rowdataObjFieldValue) ? null : rowdataObjFieldValue.toString();
                        ;
                        //获取单位符号
                        String colvalueUnit = oConvertUtils.isEmpty(row2ColModel.getNewColsValueUnitSymboles()) || row2ColModel.getNewColsValueByFields().length != row2ColModel.getNewColsValueUnitSymboles().length || oConvertUtils.isEmpty(row2ColModel.getNewColsValueUnitSymboles()[k] ) ? "" : row2ColModel.getNewColsValueUnitSymboles()[k];
                        cellValue.put(row2ColModel.getNewColsValueByFields()[k],colvalue + colvalueUnit);
                        //key=列名，例如：语文 英语
                        //value=数值+单位，例如：98% 69% 20人
                        // valueUnitSymboles

                        //是否有转义字典码
//                        if(oConvertUtils.isEmpty(row2ColModel.getRow2colsKeyFieldsDict()) || oConvertUtils.isEmpty(row2ColModel.getRow2colsKeyFieldsDict()[i].get(colname)) ){
//                            //没有转义字典码
//                            rowJSON.put((String) colname+ colvalueUnit, colvalue + colvalueUnit);
//                            //记录唯一列名：用于补零
//                            if (!newColNamesList.contains(colname) ) { // 如果新集合中不存在则插入
//                                colvalueJson.put(row2ColModel.getNewColsValueByFields()[k],colvalue+colvalueUnit);
////                                newColNamesList.add(colvalueJson);
////                                newColCount++;//新增列数加1
//                            }
//                            //列已存在，则加入记录
//                            else{
//                                JSONObject colvalueJson = new JSONObject();
//                                colvalueJson.put(row2ColModel.getNewColsValueByFields()[k],colvalue+colvalueUnit);
//                                newColNamesList.add(colvalueJson);
//
//                            }
//                        }else{}
                        if(oConvertUtils.isNotEmpty(row2ColModel.getRow2colsKeyFieldsDict()) && oConvertUtils.isNotEmpty(row2ColModel.getRow2colsKeyFieldsDict()[i].get(colname)) ){
                            String dictKey ="";
                            for (Map<String,String> dict:row2ColModel.getRow2colsKeyFieldsDict()
                                 ) {
                                if(dict.containsKey(dict)){dictKey = dict.get(row2ColModel.getNewColsValueByFields()[k]); break;}
                            }
                            String colvalueDict = colvalue + colvalueUnit+"[待转义"+dictKey+"]";//用字典转义结果值
                            cellValue.put(row2ColModel.getNewColsValueByFields()[k]+"_dictText",colvalueDict);

//                            //有转义字典码
//                            rowJSON.put(row2ColModel.getRow2colsKeyFieldsDict()[i].get(colname), colvalue + colvalueUnit);
//                            //记录唯一列名：用于补零
//                            if (!newColNamesList.contains(row2ColModel.getRow2colsKeyFieldsDict()[i].get(colname)) ) { // 如果新集合中不存在则插入
//                                newColNamesList.add(row2ColModel.getRow2colsKeyFieldsDict()[i].get(colname));
//                                newColCount++;//新增列数加1
//                            }
                        }



                        //聚合函数计算聚合值，如果需要权重计算，则进行权重计算
//                        if (oConvertUtils.isNotEmpty(row2ColModel.getGroupCalculationFun()) && oConvertUtils.isNotEmpty(row2ColModel.getGroupCalculationAsColName())
//                                && oConvertUtils.isNotEmpty(row2ColModel.getGroupCalculationFunForValueField())
//                        ) {
//                            rowJSON = getResultByGroupCalculationFun(rowJSON,rowdata,row2ColModel,k,newColNamesList,newColCount);
//                        }

                    }

                    //把单元格元素加入到结果集
                    String cellValueStr ="";//""<template>"; //前端不生效
                    for (String key:cellValue.keySet()
                         ) {
                        if(key.toLowerCase().contains("name".toLowerCase()) ) {
                            //(key.toLowerCase().indexOf("name".toLowerCase()) >=1)
                            cellValueStr +=  cellValue.get(key)+"\n";//+"\r\n</br></span>"; //前端不生效
                        }
                    }
                    // cellValueStr +="</template>"; //前端不生效
                    rowJSON.put(colname,cellValueStr); //为了方便显示，把名称value放进去，在前端直接显示

//                    rowJSON.put(colname,cellValue.get("teacherId"));
                    rowJSON.put(colname+"_JSON",cellValue);
                    //记录唯一列名：用于补零
                    if (!newColNamesList.contains(colname) ) {
                        // 如果新集合中不存在则插入
                        newColNamesList.add(colname);
                        newColCount++;//新增列数加1
                    }
                }
            }
        }

        //累计列数
        colCount = colCount+newColCount;
//        row2ColModel.setColCount(colCount); //设置列数
        row2ColModel.setResultColNmaes(newColNamesList.toArray(new String[newColNamesList.size()])); //列名称
        row2ColModel.setColCount(newColNamesList.size()); //设置列数

        //补零：数据缺失字段补零操作
        for(JSONObject jo : resultJSONList){
            for(String colname : row2ColModel.getResultColNmaes()){
                if(!jo.containsKey(colname)){
                    //设置默认值，如果默认值为null，则直接给0
                    jo.put(colname,oConvertUtils.isEmpty(row2ColModel.getNewColsNullValueByString() ) ? "0" : row2ColModel.getNewColsNullValueByString());
                }
            }
        }

        return resultJSONList;
    }

    /**
     * 行转列方法，返回二维数组
     * @param dataList
     * @return List<JSONObject>
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    @Override
    public String[][] Row2ColTo2DArray(List dataList, Row2ColModel row2ColModel) throws NoSuchFieldException, IllegalAccessException{

        List<JSONObject> jsonObjList = Row2ColToListJson(dataList,row2ColModel);
        //
        if(oConvertUtils.listIsEmpty(dataList) || oConvertUtils.isEmpty(row2ColModel) || oConvertUtils.listIsEmpty(jsonObjList) || row2ColModel.getRowCount() <=0 || row2ColModel.getColCount() <=0
                || oConvertUtils.isEmpty(row2ColModel.getResultColNmaes()) || row2ColModel.getResultColNmaes().length <=0  ){
            return null;
        }

        String[][] tableData2DArray = new String[row2ColModel.getRowCount()+1][row2ColModel.getColCount()];


        for(int j=0;j<row2ColModel.getColCount();j++){
            String kekColName = row2ColModel.getResultColNmaes()[j];
            tableData2DArray[0][j] = kekColName;
        }
        for(int i =1 ;i<row2ColModel.getRowCount()+1;i++){
            for(int j=0;j<row2ColModel.getColCount();j++){
                String kekColName = row2ColModel.getResultColNmaes()[j];
                JSONObject jsobj = jsonObjList.get(i-1);
                tableData2DArray[i][j] = oConvertUtils.isEmpty(jsobj) || oConvertUtils.isEmpty(  jsobj.get(kekColName)) ? "" : jsobj.get(kekColName).toString();
            }
        }
        return tableData2DArray;
    }

    /**
     * 按照聚合函数进行聚合计算
     * @param rowJSON
     * @param rowdata
     * @param row2ColModel
     * @param k
     * @param newColNamesList
     * @param newColCount
     * @return
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public JSONObject getResultByGroupCalculationFun(JSONObject rowJSON,Object rowdata,Row2ColModel row2ColModel,int k,List<String> newColNamesList,int newColCount) throws NoSuchFieldException, IllegalAccessException {
        for(int m=0;m<row2ColModel.getGroupCalculationFunForValueField().length;m++){
            //如果再目标字段上则进行累加计算,正在处理的字段是聚合目标字段，（非目标字段不需要聚合）
            if( row2ColModel.getNewColsValueByFields()[k].equals(row2ColModel.getGroupCalculationFunForValueField()[m])){

                //按照聚合函数列表挨个进行计算，每次计算一种函数，例如sum count等
                for(int n=0;n<row2ColModel.getGroupCalculationFun().length;n++) {
                    //获取属性值
                    Object rowdataObjFieldValue = BeanObjUtil.getFieldValueByName(rowdata,row2ColModel.getGroupCalculationFunForValueField()[m]);
                    BigDecimal newColVaule = oConvertUtils.isEmpty(rowdataObjFieldValue) ? new BigDecimal(0) : new BigDecimal(rowdataObjFieldValue.toString());// colnamefield.get(rowdata).toString();


                    String newColName = row2ColModel.getGroupCalculationAsColName()[m][n];
                    String groupFun = row2ColModel.getGroupCalculationFun()[n].toUpperCase();

                    if (!newColNamesList.contains(newColName)) { // 如果新集合中不存在则插入
                        newColNamesList.add(newColName);
                        newColCount++;//新增列数加1
                    }

                    if(! rowJSON.containsKey(newColName)){
                        //max min 函数直接使用初始值赋值
                        if("COUNT".equals(groupFun)){
                            newColVaule = new BigDecimal(1);
                        }
                        else if("SUM".equals(groupFun) && oConvertUtils.isNotEmpty(row2ColModel.getNewValueWeightCoefficientFieldes()) && oConvertUtils.isNotEmpty(newColVaule) ){
                            //获取属性值 //权重所在的列名：例如：语文权=0.1 数学权=0.1 优权=1 良权=1等
                            Object  weightCoefficientValue = BeanObjUtil.getFieldValueByName(rowdata,row2ColModel.getNewValueWeightCoefficientFieldes());
                            BigDecimal sumWeightCoefficientValue = oConvertUtils.isEmpty(weightCoefficientValue) ? new BigDecimal(1) : new BigDecimal(weightCoefficientValue.toString());

                            newColVaule = sumWeightCoefficientValue.multiply(newColVaule);
                        }

                    }
                    else {
                        //否则进行累加操作
                        if("COUNT".equals(groupFun)){
                            newColVaule = new BigDecimal(rowJSON.get(newColName).toString()).add(new BigDecimal(1));
                        }
                        else if("SUM".equals(groupFun) ){
                            if(oConvertUtils.isNotEmpty(row2ColModel.getNewValueWeightCoefficientFieldes()) && oConvertUtils.isNotEmpty(newColVaule) ){
                                Object  weightCoefficientValue = BeanObjUtil.getFieldValueByName(rowdata,row2ColModel.getNewValueWeightCoefficientFieldes());
                                double sumWeightCoefficientValue = oConvertUtils.isEmpty(weightCoefficientValue) ? 1.0 : Double.valueOf(weightCoefficientValue.toString());
                                System.out.println("权重："+weightCoefficientValue.toString()+",newColVaule11="+newColVaule);
                                BigDecimal newDouble = new BigDecimal(rowJSON.get(newColName).toString());
                                newColVaule = newColVaule.add(newDouble.multiply(new BigDecimal(sumWeightCoefficientValue)));

                            }else{
                                System.out.println("========================="+newColVaule);

                                newColVaule = newColVaule.add(new BigDecimal(rowJSON.get(newColName).toString()));

                                System.out.println("========================="+newColVaule);
                            }


                        }
                        else if( "MAX".equals(groupFun)){
                            newColVaule = newColVaule.compareTo(new BigDecimal(rowJSON.get(newColName).toString()))  >=0 ? newColVaule : new BigDecimal(rowJSON.get(newColName).toString());

                        }
                        else if( "MIN".equals(groupFun) ){
                            newColVaule = newColVaule.compareTo(new BigDecimal(rowJSON.get(newColName).toString()))  <0 ? newColVaule : new BigDecimal(rowJSON.get(newColName).toString());
                        }
                        else{
                            newColVaule = newColVaule.add(new BigDecimal(rowJSON.get(newColName).toString()));
                        }
                    }
                    rowJSON.put(newColName,newColVaule.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
                }
            }
        }
        return rowJSON;
    }


}
